package by.wind.drebedengi.database;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import by.wind.drebedengi.R;
import by.wind.drebedengi.datalayer.bean.Category;
import by.wind.drebedengi.datalayer.bean.Currency;
import by.wind.drebedengi.datalayer.bean.Login;
import by.wind.drebedengi.datalayer.bean.Place;
import by.wind.drebedengi.datalayer.bean.Record;
import by.wind.drebedengi.datalayer.bean.Source;

import com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper;
import com.j256.ormlite.dao.RuntimeExceptionDao;
import com.j256.ormlite.stmt.QueryBuilder;
import com.j256.ormlite.support.ConnectionSource;
import com.j256.ormlite.table.TableUtils;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;

public class MyDatabaseHelper extends OrmLiteSqliteOpenHelper {

	private static final String DATABASE_NAME = "drebedengi.db";
	private static final int DATABASE_VERSION = 1;
	
	
	// Runtime DAO
	private RuntimeExceptionDao<Login, Integer> itsLoginRuntimeDao = null;
	private RuntimeExceptionDao<Currency, Integer> itsCurrencyRuntimeDao = null;
	private RuntimeExceptionDao<Place, Integer>    itsPlaceRuntimeDao = null;
	private RuntimeExceptionDao<Category, Integer> itsCategoryRuntimeDao = null;
	private RuntimeExceptionDao<Source, Integer>   itsSourceRuntimeDao = null;
	private RuntimeExceptionDao<Record, Integer>   itsRecordRuntimeDao = null;
    
    public MyDatabaseHelper(Context context) {
    	super(context, DATABASE_NAME, null, DATABASE_VERSION, R.raw.ormlite_config);
    }
    

	@Override
	public void onCreate(SQLiteDatabase db, ConnectionSource connectionSource) {
		try {
			Log.i(MyDatabaseHelper.class.getName(), "onCreate");
			TableUtils.createTable(connectionSource, Login.class);
			TableUtils.createTable(connectionSource, Place.class);
			TableUtils.createTable(connectionSource, Currency.class);
			TableUtils.createTable(connectionSource, Category.class);
			TableUtils.createTable(connectionSource, Source.class);
			TableUtils.createTable(connectionSource, Record.class);
		} catch (SQLException e) {
			Log.e(MyDatabaseHelper.class.getName(), "Can't create database", e);
			throw new RuntimeException(e);
		}
	}
	
	public void save(Currency currency) {
		RuntimeExceptionDao<Currency, Integer> dao = getCurrencyDataDao();
		dao.create(currency);
	}
	
	public void save(Login login) {
		RuntimeExceptionDao<Login, Integer> dao = getLoginDataDao();
		dao.create(login);
	}
	
	public void save(Place place) {
		RuntimeExceptionDao<Place, Integer> dao = getPlaceDataDao();
		dao.create(place);
	}
	public void save(Category category) {
		RuntimeExceptionDao<Category, Integer> dao = getCategoryDataDao();
		dao.create(category);
	}
	
	public void save(Source source) {
		RuntimeExceptionDao<Source, Integer> dao = getSourceDataDao();
		dao.create(source);
	}
	
	public void save(Record record) {
		RuntimeExceptionDao<Record, Integer> dao = getRecordDataDao();
		dao.create(record);
	}

	
	public long generateNextClientIdRecord() {
		long result = 0;
		RuntimeExceptionDao<Record, Integer> dao = getRecordDataDao();
		QueryBuilder<Record,Integer> queryBuilder = dao.queryBuilder();
		queryBuilder.selectRaw("MAX("+Record.SUM+")");
		try {
			String[] values = dao.queryRaw(queryBuilder.prepareStatementString()).getFirstResult();
			return Long.parseLong(values[0]) + 1;
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
		
		
		return result;
	}
	
	public void updateCategoryList(ArrayList<Category> category) {
		RuntimeExceptionDao<Category, Integer> dao = getCategoryDataDao();
		//ArrayList<Category> clientListCategory = (ArrayList<Category>) dao.queryForAll();
		for(Category elementInServerList : category) {
			/*for(Category elementInClientList: clientListCategory) {
				if (elementInServerList.getServer_id() == elementInClientList.getServer_id())
					elementInServerList.setClient_id(elementInClientList.getClient_id());
			}*/
			dao.createOrUpdate(elementInServerList);
		}
	}
	
	public void updatePlaceList(ArrayList<Place> place) {
		RuntimeExceptionDao<Place, Integer> dao = getPlaceDataDao();
		//ArrayList<Category> clientListCategory = (ArrayList<Category>) dao.queryForAll();
		for(Place elementInServerList : place) {
			/*for(Category elementInClientList: clientListCategory) {
				if (elementInServerList.getServer_id() == elementInClientList.getServer_id())
					elementInServerList.setClient_id(elementInClientList.getClient_id());
			}*/
			dao.createOrUpdate(elementInServerList);
		}
	}
	
	public void updateCurrencyList(ArrayList<Currency> currency) {
		RuntimeExceptionDao<Currency, Integer> dao = getCurrencyDataDao();
		//ArrayList<Currency> clientListCurrency = (ArrayList<Currency>) dao.queryForAll();
		for(Currency elementInServerList : currency) {
			/*for(Currency elementInClientList: clientListCurrency) {
				if (elementInServerList.getId() == elementInClientList.getId())
					elementInServerList.setClient_id(elementInClientList.getClient_id());
			}*/
			dao.createOrUpdate(elementInServerList);
		}
	}
	
	public void updateSourceList(ArrayList<Source> source) {
		RuntimeExceptionDao<Source, Integer> dao = getSourceDataDao();
		for(Source elementInServerList : source) {
			dao.createOrUpdate(elementInServerList);
		}
	}
	
	public void updateRecordList(ArrayList<Record> category) {
		RuntimeExceptionDao<Record, Integer> dao = getRecordDataDao();
		ArrayList<Record> clientListRecord = (ArrayList<Record>) dao.queryForAll();
		for(Record elementInServerList : category) {
			for(Record elementInClientList: clientListRecord) {
				if (elementInServerList.getServer_id() == elementInClientList.getServer_id())
					elementInServerList.setClient_id(elementInClientList.getClient_id());
			}
			dao.createOrUpdate(elementInServerList);
		}
	}
	
	@Override
	public void onUpgrade(SQLiteDatabase db, ConnectionSource connectionSource, int oldVersion, int newVersion) {
		try {
			Log.i(MyDatabaseHelper.class.getName(), "onUpgrade");
			TableUtils.dropTable(connectionSource, Login.class, true);
			TableUtils.dropTable(connectionSource, Currency.class, true);
			TableUtils.dropTable(connectionSource, Place.class, true);
			TableUtils.dropTable(connectionSource, Category.class, true);
			TableUtils.dropTable(connectionSource, Source.class, true);
			TableUtils.dropTable(connectionSource, Record.class, true);
			// after we drop the old databases, we create the new ones
			onCreate(db, connectionSource);
		} catch (SQLException e) {
			Log.e(MyDatabaseHelper.class.getName(), "Can't drop databases", e);
			throw new RuntimeException(e);
		}
		
	}
	
	public RuntimeExceptionDao<Login, Integer> getLoginDataDao() {
		if (itsLoginRuntimeDao == null) {
			itsLoginRuntimeDao = getRuntimeExceptionDao(Login.class);
		}
		return itsLoginRuntimeDao;
	}
	
	public RuntimeExceptionDao<Currency, Integer> getCurrencyDataDao() {
		if (itsCurrencyRuntimeDao == null) {
			itsCurrencyRuntimeDao = getRuntimeExceptionDao(Currency.class);
		}
		return itsCurrencyRuntimeDao;
	}
	
	public RuntimeExceptionDao<Category, Integer> getCategoryDataDao() {
		if (itsCategoryRuntimeDao == null) {
			itsCategoryRuntimeDao = getRuntimeExceptionDao(Category.class);
		}
		return itsCategoryRuntimeDao;
	}
	
	public RuntimeExceptionDao<Record, Integer> getRecordDataDao() {
		if (itsRecordRuntimeDao == null) {
			itsRecordRuntimeDao = getRuntimeExceptionDao(Record.class);
		}
		return itsRecordRuntimeDao;
	}
	
	public RuntimeExceptionDao<Source, Integer> getSourceDataDao() {
		if (itsSourceRuntimeDao == null) {
			itsSourceRuntimeDao = getRuntimeExceptionDao(Source.class);
		}
		return itsSourceRuntimeDao;
	}
	
	public RuntimeExceptionDao<Place, Integer> getPlaceDataDao() {
		if (itsPlaceRuntimeDao == null) {
			itsPlaceRuntimeDao = getRuntimeExceptionDao(Place.class);
		}
		return itsPlaceRuntimeDao;
	}

	public boolean isRecordsExists(){
		try {
			QueryBuilder<Record, Integer> qb = getRecordDataDao().queryBuilder();
			List<Record> recordList = getRecordDataDao().query(qb.limit(Long.valueOf(1)).where().gt(Record.CLIENT_ID, 0).prepare());
			if (recordList.size()>0)
				return true;
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return false;
	}
	
	/**
	 * Close the database connections and clear any cached DAOs.
	 */
	@Override
	public void close() {
		itsLoginRuntimeDao = null;
		itsCurrencyRuntimeDao = null;
		itsCategoryRuntimeDao = null;
		itsPlaceRuntimeDao = null;
		itsSourceRuntimeDao = null;
		itsRecordRuntimeDao = null;
		super.close();
	}

}
